function Sprite(config) {
  for (var attr in config) {
    this[attr] = config[attr];
  }
  this.currentPointIndex = 0;
}

Sprite.prototype = {
  constructor: Sprite,
  name: '',
  x: 0,
  y: 0,
  baseSpeed: 0.1,
  speedX: 0,
  speedY: 0,
  animations: null,
  defaultAnimationId: null,
  currentAnimation: null,
  standAnimation: '',
  path: null,
  endX: 0,
  endY: 0,
  startPoint: null,
  endPoint: null,
  nextPointIndex: 0,
  currentPointIndex: 0,
  finishCallback: null,
  pauseThrowNumber: 0,
  
  init: function() {
    for (var id in this.animations){
      var animation = this.animations[id];
      animation.id = id;
      animation.init();
    }
    this.setAnimation(this.defaultAnimationId);
  },
  
  setAnimation: function(id) {
    this.currentAnimation = this.animations[id];
    this.currentAnimation.setFrame(0);
  },

  update: function(deltaTime) {
    if (this.path) {
      if (this.x == this.endX && this.y == this.endY) {
        
        // Reach the end point.
        if (this.nextPointIndex == this.path.length) {
          this.setAnimation('static');
          this.path = null;
          var currentLocation = Chess.points[this.currentPointIndex];
          if (this.finishCallback)
            this.finishCallback(currentLocation);
          return;
        }

        // Set start point.
        this.startPoint = this.path[this.nextPointIndex - 1];
        this.x = this.startPoint[0];
        this.y = this.startPoint[1];

        // Set end point.
        this.endPoint = this.path[this.nextPointIndex];
        this.endX = this.endPoint[0];
        this.endY = this.endPoint[1];

        this.setSpeed();
        // this.changeAnimation();
        this.nextPointIndex++;
      }

      var stepX = this.speedX * deltaTime;
      var stepY = this.speedY * deltaTime;
      this.x += stepX;
      this.y += stepY;

      if (this.x * this.speedX > this.endX * this.speedX)
        this.x = this.endX;
      if (this.y * this.speedY > this.endY * this.speedY)
        this.y = this.endY;
    }

    if (this.currentAnimation) {
      this.currentAnimation.update(deltaTime);
    }
  },

  jump: function(pointIndex) {
    var point = Chess.points[pointIndex];
    this.currentPointIndex = pointIndex;
    this.x = point[0];
    this.y = point[1];
  },

  setPath: function(startPointIndex, endPointIndex, finishCallback) {
    if (this.path) {
      return;
    }
    this.finishCallback = finishCallback;
    this.jump(startPointIndex);

    var points = Chess.points;
    if (endPointIndex < 0)
      endPointIndex = 0;
    if (endPointIndex > points.length - 1)
      endPointIndex = points.length - 1;
    
    this.currentPointIndex = endPointIndex;
    
    if (startPointIndex < endPointIndex) {
      points = points.slice(startPointIndex, endPointIndex + 1);
    } else {
      points = points.slice(endPointIndex, startPointIndex + 1).reverse();
    }
    
    this.nextPointIndex = 2;
    this.endPoint = points[1];
    this.endX = this.endPoint[0];
    this.endY = this.endPoint[1];

    this.setSpeed();
    // this.changeAnimation();
    this.setAnimation('glint');
    this.path = points;
  },
  
  setSpeed: function() {
    var distanceX = this.endX - this.x;
    var distanceY = this.endY - this.y;
    this.speedX = distanceX > 0 ? this.baseSpeed : -this.baseSpeed;
    this.speedY = distanceY > 0 ? this.baseSpeed : -this.baseSpeed;

    if (Math.abs(distanceX) > Math.abs(distanceY)) {
      this.speedY = distanceY / distanceX * this.speedX;
    } else {
      this.speedX = distanceX / distanceY * this.speedY;
    }
  },

  changeAnimation: function() {
    if (this.x < this.endX) {
      this.setAnimation('walk-right');
      this.standAnimation = 'stand-right';
    } else {
      this.setAnimation('walk-left');
      this.standAnimation = 'stand-left';
    }
  },

  setSize: function() {
    var spriteConfig = Config.sprite;
    var spriteRatio = spriteConfig.ratio;
    var dw = spriteConfig.width * spriteRatio;
    var dh = spriteConfig.height * spriteRatio;
    
    var animations = this.animations;
    for (var id in animations) {
      var frames = animations[id].frames;
      frames.forEach(function(frame) {
        frame.dw = dw;
        frame.dh = dh;
      });
    }
  },
  
  draw: function(context) {
    if (this.currentAnimation){
      var x = this.x + this.positionOffset.x;
      var y = this.y + this.positionOffset.y;
      this.currentAnimation.draw(context, x, y);
    }
  }
};

